/*****************************
 *@file: BaseMonsterCharacter
 *@author: 陈吕唐
 *@desc: 
 *@date: 2024-03-19	11:23
 *****************************/
import { NodePool, _decorator, math, sp, v2 } from 'cc';
import { BaseCharacter } from '../BaseCharacter';
import { BaseCharacterUI } from '../BaseCharacterUI';
import GameUtils from '../GameUtils';
import IBaseBulletValue from '../bullet/IBaseBulletValue';
import IMonsterAttribute from './IMonsterAttribute';
const { ccclass, property } = _decorator;

@ccclass('BaseMonsterCharacter')
export class BaseMonsterCharacter extends BaseCharacterUI implements IMonsterAttribute {
    /****************************************************************************************************************
     *Readonly 常量
     ****************************************************************************************************************/
    /****************************************************************************************************************
     *Property 定义变量
     ****************************************************************************************************************/
    /***************************************************************
    * 属性
    ***************************************************************/
    /**
     * 当前怪物移动速度
     */
    private _moveSpeed: number = 100;
    /***************************************************************
    * 
    ***************************************************************/
    /**
    * 对象池
    */
    private pool: NodePool = undefined!;
    /***************************************************************
    *PropertyUI 引用的控件
    ***************************************************************/
    @property({ group: { name: '基础怪物视图', id: '3' }, type: sp.Skeleton, tooltip: `播放的骨骼动画` })
    protected spine: sp.Skeleton = undefined!;
    /****************************************************************************************************************
     * Lifecycle 生命周期相关方法
     ****************************************************************************************************************/
    /****************************************************************************************************************
     * Public 公有方法
     ****************************************************************************************************************/
    public override unuse(): void {
        super.unuse();
        this.node.setPosition(0, 0, 0);
        this.node.eulerAngles = math.Vec3.ZERO;
        this.node.setRotationFromEuler(0, 0, 0);
        this.body.linearVelocity = math.Vec2.ZERO;
        this.body.angularVelocity = 0;
    }

    public override reuse(values: any[]) {
        super.reuse(values);
        this.pool = values[0];
    }

    public init(value: IMonsterAttribute): void {
        super.init(value);
        this._moveSpeed = value.moveSpeed;
    }
    /****************************************************************************************************************
     * private 私有方法
     ****************************************************************************************************************/
    /**
     * 
     */
    public override startGame(): void {
        super.startGame();
        this.spine.setAnimation(0, `run`, true);
        this.updateMoveSpeed();
    }

    protected override dead(): void {
        super.dead();
        /**
         * 播放死亡动画
         */
        let promise = GameUtils.playAnimationPromise(`die`, this.spine)
        promise.then(
            (value) => {
                this.recycle();
            }, (error) => {
                this.recycle();
            }
        )
    }


    /**
     * 
     * @param character 
     */
    protected override onHit(character: BaseCharacter): void {
        super.onHit(character);

        if (!character.gameIng) {
            return;
        }

        this.enemySet.add(character);

    }

    protected override characterAction(): void {
        super.characterAction();

        /**
         * 去除死亡的对象
         */
        let values = Array.from(this.enemySet.values());
        let removes = values.filter(v => !v.gameIng);
        for (let i = 0; i < removes.length; i++) {
            const element = removes[i];
            this.enemySet.delete(element);
        }

        /**
         * 
         */
        if (this.enemySet.size <= 0) {
            return;
        }

        let array = Array.from(this.enemySet.values());
        let character = array[0];

        let damage = this.normalDamage();
        let value: IBaseBulletValue = { value: damage };
        character.takeDamage(value, this);

        let promise = GameUtils.playAnimationPromise(`attack_01`, this.spine);
        promise.then(
            (value) => {
                this.spine.setAnimation(0, `idle`, true);
            }, (error) => {
            }
        )

    }

    /**
     * 撞击到边界处理
     */
    protected override onBorder(): void {
        this.dead();
    }


    /**
     * 回收
     */
    protected recycle(): void {
        this.scheduleOnce(() => {
            if (this.pool) {
                this.pool.put(this.node);
            } else {
                this.node.removeFromParent();
            }
        }, 0);
    }
    /**********************************************
     * 
     **********************************************/
    /**
     * 更新怪物移动速度(方向不变大小修改)
     * @param value 
     */
    private updateMoveSpeed(value: number = this.moveSpeed): void {
        if (!this.enabledInHierarchy) {
            return;
        }

        if (value <= 0) {
            this.body.linearVelocity = math.Vec2.ZERO;
            return;
        }

        let v = v2(-1, 0);

        /**
         * 速度为0时，设置为默认速度
         */
        if (v.lengthSqr() <= 0) {
            v = v2(value, 0);
        }

        v.normalize();
        v.multiplyScalar(value);

        this.body.linearVelocity = v;
    }
    /****************************************************************************************************************
     * Property Get && Set 属性的 get && set 函数
     ****************************************************************************************************************/
    public get moveSpeed(): number {
        return this._moveSpeed;
    }
    public set moveSpeed(value: number) {
        this._moveSpeed = value;
        this.updateMoveSpeed(value);
    }
}


